package io.itit.ecp.admin.provide.helper;

import io.itit.ecp.admin.common.constants.ChartConstants;
import io.itit.ecp.admin.common.constants.ParamConstants;
import io.itit.ecp.admin.common.enums.IEnergyTypeEnums;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.common.enums.StatisticsModeEnums;
import io.itit.ecp.admin.common.enums.UnitEnums;
import io.itit.ecp.admin.common.utils.EcpAdminUtils;
import io.itit.ecp.admin.provide.action.req.VisualizingQueryReq;
import io.itit.ecp.admin.provide.action.resp.EnergyDataResp;
import io.itit.ecp.admin.provide.action.resp.statistics.ChartBaseResp;
import io.itit.ecp.admin.provide.action.resp.statistics.ChartYAxisResp;
import io.itit.ecp.admin.provide.action.resp.statistics.ChartYDataResp;
import io.itit.ecp.admin.provide.action.resp.statistics.StatisticsDataResp;
import io.itit.ecp.admin.provide.utils.VisParamUtils;
import io.itit.ecp.admin.server.entity.CarbonSinkDataEntity;
import io.itit.ecp.admin.server.entity.EnergyDataEntity;
import io.itit.ecp.admin.server.entity.extend.CarbonSinkDataExtEntity;
import io.itit.ecp.admin.server.entity.extend.EnergyDataExtEntity;
import io.itit.ecp.admin.server.service.ICarbonSinkDataService;
import io.itit.ecp.admin.server.service.IEnergyDataService;
import io.itit.grass.common.enums.IUnitEnums;
import io.itit.grass.common.provide.utils.ParamUtils;
import io.itit.grass.common.server.dto.ParamDto;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.common.utils.Y666Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 可视化平台相关数据处理辅助类
 */
@Component
public class VisualizingHelper implements InitializingBean {

    @Resource
    private IEnergyDataService energyDataService;

    @Resource
    private ICarbonSinkDataService carbonSinkDataService;

    private static VisualizingHelper visualizingHelper;

    public static VisualizingHelper i() {
        return visualizingHelper;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        visualizingHelper = this;
    }

    /**
     * 统计能源趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp energy(VisualizingQueryReq req, String title, String describe) {
        // 查询数据 -> 按日期和能源类型Id分组
        Map<String, BigDecimal> resultMap = getCarbonEmissionSumGroupSolidifyDateAndEnergyType(req);

        // 计算单位
        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(resultMap.values());

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 电
        List<String> electricList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IEnergyTypeEnums.Type.electric.type))))
                .collect(Collectors.toList());
        // 水
        List<String> waterList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IEnergyTypeEnums.Type.water.type))))
                .collect(Collectors.toList());
        // 冷
        List<String> coldList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IEnergyTypeEnums.Type.cold.type))))
                .collect(Collectors.toList());

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("电", IEnergyTypeEnums.Type.electric.unit, ChartConstants.CHART_TYPE_LINE, electricList));
        yDataRespList.add(buildYData("水", IEnergyTypeEnums.Type.water.unit, ChartConstants.CHART_TYPE_LINE, waterList));
        yDataRespList.add(buildYData("冷", IEnergyTypeEnums.Type.cold.unit, ChartConstants.CHART_TYPE_LINE, coldList));

        StatisticsDataResp electricResp = buildData("用电量", IEnergyTypeEnums.Type.electric.unit, getSumValue(electricList));
        StatisticsDataResp waterResp = buildData("用水量", IEnergyTypeEnums.Type.water.unit, getSumValue(waterList));
        StatisticsDataResp coldResp = buildData("用冷量", IEnergyTypeEnums.Type.cold.unit, getSumValue(coldList));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .extraData(Arrays.asList(electricResp, waterResp, coldResp))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }


    /**
     * 统计碳排放趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonEmission(VisualizingQueryReq req, String title, String describe) {
        // 查询碳排数据
        Map<String, BigDecimal> resultMap = getCarbonEmissionSumGroupSolidifyDate(req);
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 碳排放数据
        List<String> carbonEmissionDataList = getValueList(dateStrList, resultMap);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排放量", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, carbonEmissionDataList));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 统计历史碳排放趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp historyCarbonEmission(VisualizingQueryReq req, String title, String describe) {

        req.setSolidifyDateStart(null);
        req.setSolidifyDateEnd(null);
        req.setStatisticsMode(StatisticsModeEnums.year.mode);

        // 查询碳排数据
        Map<String, BigDecimal> resultMap = getCarbonEmissionSumGroupSolidifyDate(req);

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        // 碳排放数据
        List<String> carbonEmissionDataList = getValueList(dateStrList, resultMap);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排放量", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionDataList));
        yDataRespList.add(buildYData("平均值", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, getAvgList(dateStrList, carbonEmissionDataList)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .extraData(Collections.singletonList(buildData("历史碳排总量", UnitEnums.kgCO2.unit, getSumValue(carbonEmissionDataList))))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 统计标准煤趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp standardCoal(VisualizingQueryReq req, String title, String describe) {
        // 查询标准煤数据
        Map<String, BigDecimal> resultMap = getStandardCoalSumGroupSolidifyDate(req);
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 标准煤数据
        List<String> standardCoalDataList = getValueList(dateStrList, resultMap);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("标准煤", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_LINE, standardCoalDataList));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgce.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    private List<String> getAvgList(List<String> dateStrList, List<String> carbonList) {
        BigDecimal avg = BigDecimal.valueOf(carbonList.stream().mapToDouble(Double::valueOf).average().orElse(0.0));
        // 计量数据均值
        return dateStrList.stream().map(t -> Y666Utils.toStrScale2(avg)).collect(Collectors.toList());
    }

    /**
     * 统计能源趋势
     *
     * @param req
     * @param title
     * @param name
     * @param unit
     * @param describe
     * @return
     */
    public ChartBaseResp consume(VisualizingQueryReq req, String title, String name, String unit, String describe) {

        // 统计计量数据
        Map<String, BigDecimal> resultMap = getCarbonEmissionSumGroupSolidifyData(req);

        // 计算单位
//        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(resultMap.values());

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 计量数据
        List<String> meterValueDataList = getValueList(dateStrList, resultMap);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData(name, unit, ChartConstants.CHART_TYPE_BAR, meterValueDataList));
        yDataRespList.add(buildYData("平均值", unit, ChartConstants.CHART_TYPE_LINE, getAvgList(dateStrList, meterValueDataList)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    private List<String> getValueList(List<String> dateStrList, Map<String, BigDecimal> resultMap) {
        return dateStrList.stream().map(t -> Y666Utils.toStrScale2(resultMap.get(t))).collect(Collectors.toList());
    }

    /**
     * 统计碳汇趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonSink(VisualizingQueryReq req, String title, String describe) {
        // 查询碳汇数据
        Map<String, BigDecimal> resultMap = getCarbonSinkSumGroupSolidifyData(req);

        // 计算单位
        // IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(resultMap.values());

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 碳汇数据
        List<String> carbonSinkDataList = getValueList(dateStrList, resultMap);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳汇", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, carbonSinkDataList));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 统计零碳趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp zeroCarbon(VisualizingQueryReq req, String title, String describe) {
        // 组装map
        Map<String, BigDecimal> resultMap = getZeroCarbonSumGroupSolidifyDateAndReadMeterType(req);

        // 计算单位
        // IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(resultMap.values());

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 储能
        List<String> type12List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType))))
                .collect(Collectors.toList());
        // 光伏发电
        List<String> type11List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType))))
                .collect(Collectors.toList());

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("储能", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, type12List));
        yDataRespList.add(buildYData("光伏发电", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, type11List));
        yDataRespList.add(buildYData("充电桩", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, type12List));

        // 储能总量
        BigDecimal type12Val = getSumValue(type12List);
        // 光伏发电总量
        BigDecimal type11Val = getSumValue(type11List);

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .extraData(Arrays.asList(buildData("储能", UnitEnums.kgCO2.unit, type12Val), buildData("光伏发电", UnitEnums.kgCO2.unit, type11Val), buildData("充电桩", UnitEnums.kgCO2.unit, type12Val)))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 统计碳中和趋势
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonNeutrality(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> carbonEmissionResultMap = getCarbonEmissionSumGroupSolidifyDate(req);
        Map<String, BigDecimal> zeroCarbonResultMap = getZeroCarbonSumGroupSolidifyData(req);
        Map<String, BigDecimal> carbonSinkResultMap = getCarbonSinkSumGroupSolidifyData(req);

        // 合并金额方便计算单位
        List<BigDecimal> amountList = new ArrayList<>();
        amountList.addAll(carbonEmissionResultMap.values());
        amountList.addAll(zeroCarbonResultMap.values());
        amountList.addAll(carbonSinkResultMap.values());

        // 计算单位
        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(amountList);

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 碳排
        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(carbonEmissionResultMap.get(t), unitEnum))
                .collect(Collectors.toList());

        // 碳减（零碳）
        List<String> zeroCarbonList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(zeroCarbonResultMap.get(t), unitEnum))
                .collect(Collectors.toList());

        // 碳汇
        List<String> carbonSinkList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(carbonSinkResultMap.get(t), unitEnum))
                .collect(Collectors.toList());

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, carbonEmissionList));
        yDataRespList.add(buildYData("碳减", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, zeroCarbonList));
        yDataRespList.add(buildYData("碳汇", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, carbonSinkList));

        // 总碳排
        BigDecimal carbonEmissionSumVal = getSumValue(carbonEmissionList);
        // 总碳减
        BigDecimal zeroCarbonSumVal = getSumValue(zeroCarbonList);
        // 总碳汇
        BigDecimal carbonSinkSumVal = getSumValue(carbonSinkList);

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(Y666Utils.unit(UnitEnums.kgCO2.unit, unitEnum))
                .extraData(Arrays.asList(buildData("总碳排", UnitEnums.kgCO2.unit, carbonEmissionSumVal),
                        buildData("总碳减", UnitEnums.kgCO2.unit, zeroCarbonSumVal),
                        buildData("总碳汇", UnitEnums.kgCO2.unit, carbonSinkSumVal)))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳中和分析
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonNeutralityAnalyze(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> carbonEmissionResultMap = getCarbonEmissionSumGroupSolidifyDate(req);
        Map<String, BigDecimal> zeroCarbonResultMap = getZeroCarbonSumGroupSolidifyData(req);
        Map<String, BigDecimal> carbonSinkResultMap = getCarbonSinkSumGroupSolidifyData(req);

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 合并金额方便计算单位
        List<BigDecimal> amountList = new ArrayList<>();
        amountList.addAll(carbonEmissionResultMap.values());
        amountList.addAll(zeroCarbonResultMap.values());
        amountList.addAll(carbonSinkResultMap.values());

        // 计算单位
        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(amountList);

        // 碳中和
        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(poor(carbonEmissionResultMap.get(t), zeroCarbonResultMap.get(t), carbonSinkResultMap.get(t)), unitEnum))
                .collect(Collectors.toList());

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳中和量", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, carbonEmissionList));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(Y666Utils.unit(UnitEnums.kgCO2.unit, unitEnum))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 预测精度
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp predictionAccuracy(VisualizingQueryReq req, String title, String describe) {
        // 组装map
        Map<String, BigDecimal> resultMap = getZeroCarbonSumGroupSolidifyDateAndReadMeterType(req);

        // 计算单位
        // IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(resultMap.values());

        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());

        // 预测
        List<String> type12List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType))))
                .collect(Collectors.toList());
        // 实际
        List<String> type11List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType))))
                .collect(Collectors.toList());

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("预测", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, type12List));
        yDataRespList.add(buildYData("实际", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, type11List));

        // 预测总量
        BigDecimal type12Val = getSumValue(type12List);
        // 实际总量
        BigDecimal type11Val = getSumValue(type11List);

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .extraData(Arrays.asList(buildData("预测", UnitEnums.kgCO2.unit, type12Val), buildData("实际", UnitEnums.kgCO2.unit, type11Val)))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    private BigDecimal getSumValue(List<String> list) {
        return list.stream().map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 可再生电力情况
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp power(VisualizingQueryReq req, String title, String describe) {
        // 查询数据 -> 按日期和读表类型分组
        List<EnergyDataExtEntity> energyDataList = energyDataService.sumGroupSolidifyDateAndReadMeterType(getZeroCarbonParam(req));

        Map<String, BigDecimal> carbonEmissionMap = energyDataList.stream()
                .collect(Collectors.toMap(t -> key(t.getSolidifyDateStr(), t.getReadMeterType()), EnergyDataExtEntity::getCarbonEmission));

        Map<String, BigDecimal> avgCarbonEmissionMap = energyDataList.stream()
                .collect(Collectors.toMap(t -> key(t.getSolidifyDateStr(), t.getReadMeterType()), EnergyDataExtEntity::getAvgCarbonEmission));

        List<BigDecimal> list = new ArrayList<>();
        list.addAll(carbonEmissionMap.values());
        list.addAll(avgCarbonEmissionMap.values());

        // 计算单位
        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(list);
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        // 储能
        List<String> type12List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(carbonEmissionMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)), unitEnum))
                .collect(Collectors.toList());
        // 储能 >> 平均值
        List<String> avg12List = getAvgList(dateStrList, carbonEmissionMap, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType, unitEnum);


        // 光伏发电
        List<String> type11List = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(carbonEmissionMap.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)), unitEnum))
                .collect(Collectors.toList());
        // 光伏发电 >> 平均值
        List<String> avg11List = getAvgList(dateStrList, avgCarbonEmissionMap, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType, unitEnum);

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();

        yDataRespList.add(buildYData("储能电量", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, type12List));
        yDataRespList.add(buildYData("储能平均值", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, avg12List));
        yDataRespList.add(buildYData("光伏发电", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, type11List));
        yDataRespList.add(buildYData("光伏平均值", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, avg11List));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(Y666Utils.unit(UnitEnums.kgCO2.unit, unitEnum))
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    private List<String> getAvgList(List<String> dateStrList, Map<String, BigDecimal> map, String readMeterType, IUnitEnums.Unit unitEnum) {
        List<String> avgList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(map.get(key(t, readMeterType)), unitEnum))
                .collect(Collectors.toList());
        BigDecimal avg = BigDecimal.valueOf(avgList.stream().mapToDouble(Double::valueOf).average().orElse(0.0));
        // 计量数据均值
        return dateStrList.stream().map(t -> Y666Utils.toStrScale2(avg, unitEnum)).collect(Collectors.toList());
    }

    /**
     * 构建Data
     *
     * @param name
     * @param unit
     * @param curVal
     * @return
     */
    public static StatisticsDataResp buildData(String name, String unit, BigDecimal curVal) {
        return StatisticsDataResp.builder()
                .name(name)
                .unit(unit)
                .value(Y666Utils.toStrScale2(curVal))
                .valueUnit(Y666Utils.toStrJoinUnit(curVal, 2, Y666Utils.calcUnit(curVal)))
                .build();
    }

    /**
     * 构建Y轴数据
     *
     * @param name
     * @param unit
     * @param type
     * @param dataList
     * @return
     */
    public ChartYDataResp buildYData(String name, String unit, String type, List<String> dataList) {
        return ChartYDataResp.builder()
                .name(name)
                .unit(unit)
                .type(type)
                .dataList(dataList)
                .build();
    }

    /**
     * 构建key
     *
     * @param keys
     * @return
     */
    public static String key(String... keys) {
        return String.join(":", keys);
    }

    public ChartBaseResp carbonEmissionContrast(VisualizingQueryReq req, String title, String describe) {
        ParamDto paramDto = ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);

        Map<String, BigDecimal> resultMap = SceneHelper.i().setSceneInfo(ConvertUtils.convert(energyDataService.sumGroupScene(paramDto), EnergyDataResp.class)).stream().collect(Collectors.toMap(EnergyDataResp::getSceneInfoName, EnergyDataResp::getCarbonEmission));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排放", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    public ChartBaseResp zeroCarbonStructure(VisualizingQueryReq req, String title, String describe) {
        ParamDto paramDto = ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);

        Map<String, BigDecimal> resultMap = SceneHelper.i().setSceneInfo(ConvertUtils.convert(energyDataService.sumGroupScene(paramDto), EnergyDataResp.class)).stream().collect(Collectors.toMap(EnergyDataResp::getSceneInfoName, EnergyDataResp::getCarbonEmission));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("零碳", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    public ChartBaseResp energyClassifyStatistics(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> resultMap = new HashMap<>();
        resultMap.put("照明",new BigDecimal("10"));
        resultMap.put("空调",new BigDecimal("100"));
        resultMap.put("充电桩",new BigDecimal("600"));
        resultMap.put("电梯",new BigDecimal("912"));
        resultMap.put("消防水泵",new BigDecimal("1150"));
        resultMap.put("消防风机",new BigDecimal("850"));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> standardCoalList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("标准煤", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, standardCoalList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgce.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    public ChartBaseResp carbonEmissionsClassifyStatistics(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> resultMap = new HashMap<>();
        resultMap.put("照明",new BigDecimal("10"));
        resultMap.put("空调",new BigDecimal("100"));
        resultMap.put("充电桩",new BigDecimal("600"));
        resultMap.put("电梯",new BigDecimal("912"));
        resultMap.put("消防水泵",new BigDecimal("1150"));
        resultMap.put("消防风机",new BigDecimal("850"));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> standardCoalList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排放", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, standardCoalList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 能源分析
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp energyAnalysis(VisualizingQueryReq req, String title, String describe) {
        ParamDto paramDto = ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        // map中的value还要分，需要可以根据产品类型获取值
        Map<String, BigDecimal> resultMap = SceneHelper.i().setSceneInfo(ConvertUtils.convert(energyDataService.sumGroupScene(paramDto), EnergyDataResp.class)).stream().collect(Collectors.toMap(EnergyDataResp::getSceneInfoName, EnergyDataResp::getStandardCoal));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("充电桩", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("电梯", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("空调", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("消防水泵", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("照明", UnitEnums.kgce.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgce.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-能源碳排放统计
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp energyCarbonEmissionsStatistics(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> resultMap = new HashMap<>();
        resultMap.put("煤",new BigDecimal("10"));
        resultMap.put("自来水",new BigDecimal("30"));
        resultMap.put("供冷",new BigDecimal("70"));
        resultMap.put("电",new BigDecimal("100"));
        resultMap.put("中水",new BigDecimal("300"));
        resultMap.put("办公用纸",new BigDecimal("200"));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("市电", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("光伏发电使用量", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("外购绿电", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-活动碳排放统计
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp activityCarbonEmissionsStatistics(VisualizingQueryReq req, String title, String describe) {
        Map<String, BigDecimal> resultMap = new HashMap<>();
        resultMap.put("化石燃料燃烧",new BigDecimal("50"));
        resultMap.put("园区建设与拆除",new BigDecimal("200"));
        resultMap.put("外购电力热力",new BigDecimal("600"));
        resultMap.put("交通",new BigDecimal("500"));
        resultMap.put("园区用水",new BigDecimal("1180"));
        resultMap.put("废弃物回收",new BigDecimal("900"));
        resultMap.put("碳抵消",new BigDecimal("-650"));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("活动碳排放统计", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-碳价/CCER价格
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonPrice(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
        }

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳配额", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(0)));
        yDataRespList.add(buildYData("CCER", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(1)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-碳汇统计
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonSequestrationStatistics(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
            dataList.get(2).add(String.valueOf(i*10));
        }

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("节能屋顶", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList.get(0)));
        yDataRespList.add(buildYData("下沉绿地1", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList.get(1)));
        yDataRespList.add(buildYData("下沉绿地2", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList.get(2)));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-碳排强度趋势
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonEmissionIntensity(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<String> dataList = new ArrayList<>();
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.add(String.valueOf(i * 10));
        }
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳排强度趋势", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-碳收益预测
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonRevenueForecast(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
        }

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("碳配额", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList.get(0)));
        yDataRespList.add(buildYData("CCER", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, dataList.get(1)));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 碳分析-碳排放分类统计
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp carbonEmissionsAnalysisClassifyStatistics(VisualizingQueryReq req, String title, String describe) {
        ParamDto paramDto = ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);

        Map<String, BigDecimal> resultMap = SceneHelper.i().setSceneInfo(ConvertUtils.convert(energyDataService.sumGroupScene(paramDto), EnergyDataResp.class)).stream().collect(Collectors.toMap(EnergyDataResp::getSceneInfoName, EnergyDataResp::getCarbonEmission));

        // 构建X轴
        List<String> dateStrList = resultMap.keySet().stream().sorted().collect(Collectors.toList());

        List<String> carbonEmissionList = dateStrList.stream()
                .map(t -> Y666Utils.toStrScale2(resultMap.get(key(t))))
                .collect(Collectors.toList());

        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("充电桩", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("电梯", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("空调", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("消防水泵", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));
        yDataRespList.add(buildYData("照明", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, carbonEmissionList));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 柔性度分析
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp flexibilityAnalysis(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
            dataList.get(2).add(String.valueOf(i*160));
            dataList.get(3).add(String.valueOf(i*200));
        }

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("储能", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(0)));
        yDataRespList.add(buildYData("充电桩", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(1)));
        yDataRespList.add(buildYData("照明", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(2)));
        yDataRespList.add(buildYData("热储", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(3)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kW.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 柔性度源调整情况
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp flexibilityAdjustment(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
            dataList.get(2).add(String.valueOf(i*160));
            dataList.get(3).add(String.valueOf(i*200));
        }

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("最大可调功率", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(0)));
        yDataRespList.add(buildYData("标准运行功率", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(1)));
        yDataRespList.add(buildYData("柔性调度功率", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(2)));
        yDataRespList.add(buildYData("最小可调功率", UnitEnums.kW.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(3)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kW.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }

    /**
     * 储能使用情况
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp energyStorageUsageStatus(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
        }

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("储能充电量", UnitEnums.kWh.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(0)));
        yDataRespList.add(buildYData("储能放电量", UnitEnums.kWh.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(1)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kWh.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .extraData(Arrays.asList(
                        StatisticsDataResp.builder().name("当天储能利用率").value("90").build(),
                        StatisticsDataResp.builder().name("当天充电次数").value("90").build(),
                        StatisticsDataResp.builder().name("当天放电次数").value("90").build()
                ))
                .build();
    }

    /**
     * 光伏发电情况
     *
     * @param req
     * @param title
     * @param describe
     * @return
     */
    public ChartBaseResp photovoltaicPowerStatus(VisualizingQueryReq req, String title, String describe) {
        // 构建X轴
        List<String> dateStrList = EcpAdminUtils.dateStr(req.getSolidifyDateStart(), req.getSolidifyDateEnd(), req.getStatisticsMode());
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            dataList.add(new ArrayList<>());
        }
        for (int i = 0; i < dateStrList.size(); i++) {
            dataList.get(0).add(String.valueOf(i*100));
            dataList.get(1).add(String.valueOf(i*130));
        }

        // 构建Y轴
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(buildYData("光伏发电量", UnitEnums.kWh.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(0)));
        yDataRespList.add(buildYData("上网电量", UnitEnums.kWh.unit, ChartConstants.CHART_TYPE_LINE, dataList.get(1)));

        // 构建返回结果
        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kWh.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .extraData(Arrays.asList(StatisticsDataResp.builder().name("消纳率").value("90%").build()))
                .build();
    }

    public BigDecimal poor(BigDecimal a, BigDecimal b, BigDecimal c) {
        return Y666Utils.subtract(Y666Utils.subtract(a, b), c);
    }

    /**
     * 统计碳排放
     *
     * @param req
     * @return
     */
    public EnergyDataExtEntity getCarbonSinkSum(VisualizingQueryReq req) {
        return energyDataService.sum(ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list));
    }

    /**
     * 统计零碳
     *
     * @param req
     * @return
     */
    public EnergyDataExtEntity getZeroCarbonSum(VisualizingQueryReq req) {
        return energyDataService.sum(ParamUtils.paramDto(req)
                // 排除零碳数据，只统计用量
                .add(ParamConstants.READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list));
    }

    /**
     * 获取能源数据按能源类型分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getCarbonEmissionSumGroupEnergyType(VisualizingQueryReq req, String type) {
        ParamDto carbonEmissionParam;
        if (ParamConstants.PRE.equals(type)) {
            carbonEmissionParam = getCarbonEmissionPreParam(req);
        } else {
            carbonEmissionParam = getCarbonEmissionParam(req);
        }
        // 查询数据 -> 按日期分组
        return getCarbonEmissionSumGroupEnergyType(carbonEmissionParam);
    }

    public Map<String, BigDecimal> getCarbonEmissionSumGroupEnergyType(ParamDto paramDto) {
        return energyDataService.sumGroupEnergyType(paramDto)
                .stream()
                .collect(Collectors.toMap(EnergyDataEntity::getEnergyTypeId, EnergyDataEntity::getCarbonEmission, (t1, t2) -> t1));
    }

    /**
     * 获取能源数据按能源类型分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getStandardCoalSumGroupEnergyType(VisualizingQueryReq req, String type) {
        ParamDto carbonEmissionParam;
        if (ParamConstants.PRE.equals(type)) {
            carbonEmissionParam = getCarbonEmissionPreParam(req);
        } else {
            carbonEmissionParam = getCarbonEmissionParam(req);
        }
        // 查询数据 -> 按日期分组
        return getStandardCoalSumGroupEnergyType(carbonEmissionParam);
    }

    public Map<String, BigDecimal> getStandardCoalSumGroupEnergyType(ParamDto paramDto) {
        return energyDataService.sumGroupEnergyType(paramDto)
                .stream()
                .collect(Collectors.toMap(EnergyDataEntity::getEnergyTypeId, EnergyDataEntity::getStandardCoal, (t1, t2) -> t1));
    }

    /**
     * 获取计量值按日期分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getCarbonEmissionSumGroupSolidifyData(VisualizingQueryReq req) {
        // 查询数据 -> 按日期分组
        return energyDataService.sumGroupSolidifyDate(getCarbonEmissionParam(req))
                .stream()
                .collect(Collectors.toMap(EnergyDataExtEntity::getSolidifyDateStr, EnergyDataEntity::getMeterValue, (t1, t2) -> t1));
    }

    /**
     * 获取碳排按日期分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getCarbonEmissionSumGroupSolidifyDate(VisualizingQueryReq req) {
        // 查询数据 -> 按日期分组
        return energyDataService.sumGroupSolidifyDate(getCarbonEmissionParam(req))
                .stream()
                .collect(Collectors.toMap(EnergyDataExtEntity::getSolidifyDateStr, EnergyDataEntity::getCarbonEmission, (t1, t2) -> t1));
    }

    /**
     * 获取零碳按日期分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getZeroCarbonSumGroupSolidifyData(VisualizingQueryReq req) {
        // 查询数据 -> 按日期分组
        return energyDataService.sumGroupSolidifyDate(getZeroCarbonParam(req))
                .stream()
                .collect(Collectors.toMap(EnergyDataExtEntity::getSolidifyDateStr, EnergyDataEntity::getCarbonEmission, (t1, t2) -> t1));
    }

    /**
     * 获取碳汇按日期分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getCarbonSinkSumGroupSolidifyData(VisualizingQueryReq req) {
        ParamDto paramDto = ParamUtils.paramDto(req)
                // 日期转换格式
                .add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        // 查询数据 -> 按日期分组
        return carbonSinkDataService.sumGroupSolidifyDate(paramDto)
                .stream()
                .collect(Collectors.toMap(CarbonSinkDataExtEntity::getSolidifyDateStr, CarbonSinkDataEntity::getCarbonEmission, (t1, t2) -> t1));
    }

    /**
     * 获取标准煤按日期分组数据
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getStandardCoalSumGroupSolidifyDate(VisualizingQueryReq req) {
        // 查询数据 -> 按日期分组
        return energyDataService.sumGroupSolidifyDate(getStandardCoalParam(req))
                .stream()
                .collect(Collectors.toMap(EnergyDataExtEntity::getSolidifyDateStr, EnergyDataEntity::getStandardCoal, (t1, t2) -> t1));
    }

    /**
     * 构建碳排放参数
     *
     * @param req
     * @return
     */
    public ParamDto getCarbonEmissionParam(VisualizingQueryReq req) {
        ParamDto paramDto = ParamUtils.paramDto(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建碳排放同比参数
     *
     * @param req
     * @return
     */
    public ParamDto getCarbonEmissionPreParam(VisualizingQueryReq req) {
        ParamDto paramDto = VisParamUtils.calcPreSolidifyDate(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建零碳参数
     *
     * @param req
     * @return
     */
    public ParamDto getZeroCarbonParam(VisualizingQueryReq req) {
        ParamDto paramDto = ParamUtils.paramDto(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建标准煤参数
     *
     * @param req
     * @return
     */
    public ParamDto getStandardCoalParam(VisualizingQueryReq req) {
        ParamDto paramDto = ParamUtils.paramDto(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.NOT_READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建零碳同比参数
     *
     * @param req
     * @return
     */
    public ParamDto getZeroCarbonPreParam(VisualizingQueryReq req) {
        ParamDto paramDto = VisParamUtils.calcPreSolidifyDate(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建能源总量参数
     *
     * @param req
     * @return
     */
    public ParamDto getTotalEnergyParam(VisualizingQueryReq req) {
        ParamDto paramDto = ParamUtils.paramDto(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 构建能源总量同比参数
     *
     * @param req
     * @return
     */
    public ParamDto getTotalEnergyPreParam(VisualizingQueryReq req) {
        ParamDto paramDto = VisParamUtils.calcPreSolidifyDate(req);
        // 排除零碳数据，只统计用量
        paramDto.add(ParamConstants.READ_METER_TYPE_LIST, ParamConstants.readMeterType_zeroCarbon_list);
        if (StringUtils.isNotEmpty(req.getStatisticsMode())) {
            // 日期转换格式
            paramDto.add(ParamConstants.MYSQL_DATE_FORMAT, StatisticsModeEnums.mysqlDateFormatVis(req.getStatisticsMode()));
        }
        return paramDto;
    }

    /**
     * 统计碳排放趋势 按照 [数据日期] 和 [能源类型] 分组
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getCarbonEmissionSumGroupSolidifyDateAndEnergyType(VisualizingQueryReq req) {
        return energyDataService.sumGroupSolidifyDateAndEnergyType(getCarbonEmissionParam(req))
                .stream()
                .collect(Collectors.toMap(t -> key(t.getSolidifyDateStr(), t.getEnergyTypeId()), EnergyDataEntity::getMeterValue, (t1, t2) -> t1));
    }

    /**
     * 统计零碳趋势 -> 按照 [数据日期] 和 [读表类型] 分组
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getZeroCarbonSumGroupSolidifyDateAndReadMeterType(VisualizingQueryReq req) {
        // 组装map
        return energyDataService.sumGroupSolidifyDateAndReadMeterType(getZeroCarbonParam(req)).stream()
                .collect(Collectors.toMap(t -> key(t.getSolidifyDateStr(), t.getReadMeterType()), EnergyDataEntity::getCarbonEmission, (t1, t2) -> t1));
    }

    /**
     * 统计零碳 -> 按照 [读表类型] 分组
     *
     * @param req
     * @return
     */
    public Map<String, BigDecimal> getZeroCarbonSumGroupReadMeterType(VisualizingQueryReq req, String type) {
        ParamDto paramDto;
        if (ParamConstants.PRE.equals(type)) {
            paramDto = getZeroCarbonPreParam(req);
        } else {
            paramDto = getZeroCarbonParam(req);
        }
        return energyDataService.sumGroupReadMeterType(paramDto)
                .stream()
                .collect(Collectors.toMap(EnergyDataExtEntity::getReadMeterType, EnergyDataExtEntity::getCarbonEmission));
    }

    public ChartBaseResp carbonNeutralityComparison(VisualizingQueryReq req, String title, String describe) {
        List<EnergyDataExtEntity> resultList = energyDataService.sumGroupReadMeterTypeAndScene(ParamUtils.paramDto(req));
        List<EnergyDataResp> sceneInfoList = SceneHelper.i().setSceneInfo(ConvertUtils.convert(resultList, EnergyDataResp.class));
        // 构建X轴
        List<String> dateStrList = sceneInfoList.stream().map(EnergyDataResp::getSceneInfoName).distinct().sorted().collect(Collectors.toList());

        Map<String, BigDecimal> respList = sceneInfoList
                .stream()
                .collect(Collectors.toMap(t -> VisualizingHelper.key(t.getSceneInfoName(), t.getReadMeterType()), EnergyDataResp::getCarbonEmission, (t1, t2) -> t1));

        // 计算单位
        IUnitEnums.Unit unitEnum = Y666Utils.calcMinUnit(respList.values());

        // 碳排放
        List<String> resultList13 = dateStrList.stream().map(t ->
                Y666Utils.add(
                        Y666Utils.add(
                                Y666Utils.add(respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType13.readMeterType)), respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType21.readMeterType)))
                                , respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType22.readMeterType)))
                        , respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType31.readMeterType))).setScale(2, RoundingMode.HALF_UP).toPlainString()
        ).collect(Collectors.toList());

        // 零碳
        List<String> resultList12 = dateStrList.stream().map(t ->
                Y666Utils.add(
                        respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)),
                        respList.get(key(t, IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType))).setScale(2, RoundingMode.HALF_UP).toPlainString()).collect(Collectors.toList());
        List<ChartYDataResp> yDataRespList = new ArrayList<>();
        yDataRespList.add(VisualizingHelper.i().buildYData("碳排放", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, resultList13));
        yDataRespList.add(VisualizingHelper.i().buildYData("零碳", UnitEnums.kgCO2.unit, ChartConstants.CHART_TYPE_BAR, resultList12));

        return ChartBaseResp.builder()
                .title(title)
                .describe(describe)
                .unit(UnitEnums.kgCO2.unit)
                .xAxis(dateStrList)
                .yAxis(ChartYAxisResp.builder().yList(yDataRespList).build())
                .build();
    }
}
